package cn.talk.doodledemo.utils.photocodeclib;

import cn.talk.doodledemo.utils.log.LogUtils;
import ohos.global.resource.Resource;
import ohos.global.resource.ResourceManager;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * @version 1.0.1
 * @description: 图像解码
 * @program: Gallery
 * @Author xiaozhijun
 * @Date 2020/12/22 14:43
 */
public class PhotoDecode implements IPhotoDecode {

    private static final String TAG = "PhotoDecode";

    ImageSource.SourceOptions sourceOptions;

    ImageSource.DecodingOptions decodingOptions;


    private PhotoDecode(ImageSource.SourceOptions sourceOptions, ImageSource.DecodingOptions decodingOptions) {
        this.sourceOptions = sourceOptions;
        this.decodingOptions = decodingOptions;
    }

    public static class Builder {
        //打包参数
        ImageSource.SourceOptions sOptions;

        //解码参数
        ImageSource.DecodingOptions dOptions;

        public Builder() {

        }

        private synchronized ImageSource.SourceOptions getSourceOptions() {
            if (sOptions == null) {
                sOptions = new ImageSource.SourceOptions();
            }
            return sOptions;
        }

        private synchronized ImageSource.DecodingOptions getDecodingOptions() {
            if (dOptions == null) {
                dOptions = new ImageSource.DecodingOptions();
            }
            return dOptions;
        }

        /**
         * 设置图像的格式
         *
         * @param format 图像格式类型
         */
        public Builder format(String format) {
            getSourceOptions().formatHint = format;
            return this;
        }

        /**
         * 设置图像的像素密度。
         *
         * @param density 像素密度值
         */
        public Builder baseDensity(int density) {
            getSourceOptions().baseDensity = density;
            return this;
        }

        /**
         * 设置图片解码时对图像附加旋转操作
         *
         * @param rotate 旋转图片的角度
         */
        public Builder rotateDegrees(int rotate) {
            getDecodingOptions().rotateDegrees = rotate;
            return this;
        }

        /**
         * 设置图片解码时对图像附加缩放操作
         *
         * @param size 缩放到指定大小
         */
        public Builder desiredSize(Size size) {
            getDecodingOptions().desiredSize = size;
            return this;
        }

        /**
         * 根据图片自身的sie设置解码时对图像附加缩放操作
         *
         * @param filePath       图片路劲
         * @param screenRealSize 屏幕size
         */
        public Builder desiredSizeByPicture(Size screenRealSize, String filePath) {
            Size imageSize = decodePhotoInJustBound(new File(filePath));
            if (imageSize != null && screenRealSize != null) {
                if (imageSize.width > screenRealSize.width) {
                    int height = screenRealSize.width * imageSize.height / imageSize.width;
                    desiredSize(new Size(screenRealSize.width, height));
                    return this;
                }
            }

            desiredSize(imageSize);
            return this;
        }

        /**
         * 设置图片解码时对图像附加裁剪操作
         *
         * @param region 裁剪区域
         */
        public Builder desiredRegion(Rect region) {
            getDecodingOptions().desiredRegion = region;
            return this;
        }

        /**
         * 设置解码时图像的采样大小
         *
         * @return
         */
        public Builder simpleSize(int simplesize) {
            getDecodingOptions().sampleSize = simplesize;
            return this;
        }

        public PhotoDecode build() {
            return new PhotoDecode(sOptions, dOptions);
        }

    }

    /**
     * 普通解码
     *
     * @param filepath 本地图像文件数据
     * @return
     */
    @Override
    public PixelMap commonDecodePhoto(String filepath) {
        PixelMap pixelMap = null;
        ImageSource imageSource = null;
        try {
            LogUtils.i("commonDecodePhoto filepath is " + filepath);
            imageSource = ImageSource.create(filepath, sourceOptions);
            pixelMap = imageSource.createPixelmap(decodingOptions);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (imageSource != null) {
                imageSource.release();
            }
        }
        return pixelMap;
    }


    /**
     * 普通解码
     *
     * @param resourceId 本地图像文件资源ID
     * @return 解码后的图像数据
     */
    public PixelMap commonDecodePhoto(ResourceManager resourceManager, int resourceId) {
        PixelMap pixelMap = null;
        try {
            LogUtils.i("commonDecodePhoto resourceId");
            Resource resource = resourceManager.getResource(resourceId);
            pixelMap = commonDecodePhoto(resource);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pixelMap;
    }

    /**
     * 普通的解码
     *
     * @param is 图像数据流
     * @return 解码后的图像数据
     */
    public PixelMap commonDecodePhoto(InputStream is) {
        PixelMap pixelMap = null;
        ImageSource imageSource = null;
        try {
            LogUtils.i("commonDecodePhoto InputStream");
            imageSource = ImageSource.create(is, sourceOptions);
            pixelMap = imageSource.createPixelmap(decodingOptions);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (imageSource != null) {
                imageSource.release();
            }
        }
        return pixelMap;
    }


    /**
     * 解码图片 仅获取图片宽高 (无法解码Resource，会出现获取的数据异常)
     *
     * @param is 图片宽高
     * @return
     */
    public Size decodePhotoInJustBound(InputStream is) {
        ImageInfoFactory imageInfoFactory = new ImageInfoFactory();
        try {
            boolean isDecodeSuccess = imageInfoFactory.decodeStream(is);
            if (isDecodeSuccess && imageInfoFactory.getWidth() > 0 && imageInfoFactory.getHeight() > 0) {
                return new Size(imageInfoFactory.getWidth(), imageInfoFactory.getHeight());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解码图片 仅获取图片宽高
     *
     * @param f 图片文件
     * @return
     */
    public static Size decodePhotoInJustBound(File f) {
        ImageInfoFactory imageInfoFactory = new ImageInfoFactory();
        try {
            boolean isDecodeSuccess = imageInfoFactory.decodeStream(f);
            if (isDecodeSuccess && imageInfoFactory.getWidth() > 0 && imageInfoFactory.getHeight() > 0) {
                return new Size(imageInfoFactory.getWidth(), imageInfoFactory.getHeight());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
